package cn.xshi.oauth.client.timer.task;
import cn.xshi.common.base.BaseResult;
import cn.xshi.common.util.CollectionUtil;
import cn.xshi.common.util.RestTemplateUtil;
import cn.xshi.oauth.client.util.OauthAttributesUtil;
import cn.xshi.oauth.client.util.TokenAttributesUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RecursiveTask;

/**
 * @Desc
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
public class CommandTokenTask  extends RecursiveTask<Integer> {

    private Map<String,Integer> map;

    int groupNumber;

    RestTemplateUtil restTemplateUtil;

    OauthAttributesUtil oauthAttributesUtil;

    TokenAttributesUtil tokenAttributesUtil;

    public CommandTokenTask(Map<String,Integer> map, int groupNumber){
        this.map = map;
        this.groupNumber = groupNumber;
    }
    public CommandTokenTask(Map<String,Integer> map, int groupNumber, RestTemplateUtil restTemplateUtil){
        this.map = map;
        this.groupNumber = groupNumber;
        this.restTemplateUtil = restTemplateUtil;
    }

    public CommandTokenTask(Map<String,Integer> map, int groupNumber, RestTemplateUtil restTemplateUtil,OauthAttributesUtil oauthAttributesUtil,TokenAttributesUtil tokenAttributesUtil){
        this.map = map;
        this.groupNumber = groupNumber;
        this.restTemplateUtil = restTemplateUtil;
        this.oauthAttributesUtil = oauthAttributesUtil;
        this.tokenAttributesUtil = tokenAttributesUtil;
    }


    @Override
    protected Integer compute() {
        int result=0;
        if(cn.hutool.core.collection.CollectionUtil.isEmpty(map)){
            return result;
        }
        if(map.size()<=groupNumber){
            //一个任务即可
            result+=doCallable(map);
        }else{
            //拆分任务
            List<CommandTokenTask> subTaskList =createSubTasks(map);
//            //方法一 采用fork（注意：该效率不是太高）
//            for(FasErrorTask subTask :subTaskList){
//                subTask.fork();//子任务计划执行
//            }

            //方法二 采用invokeAll（注意：该效率高一些）
            invokeAll(subTaskList);

            //合并执行结果
            for(CommandTokenTask subTask :subTaskList){
                result+=subTask.join();
            }
        }
        return result;
    }

    /**
     *
     * @param map
     * @return
     */
    private Integer doCallable(Map<String,Integer> map){
        Integer result = pull(map);
        return result;
    }

    /**
     * 创建子任务
     * @param map
     * @return
     */
    private List<CommandTokenTask> createSubTasks(Map<String,Integer> map) {
        List<CommandTokenTask> subTasks = new ArrayList<CommandTokenTask>();
        List<Map<String,Integer>> dataMap = CollectionUtil.mapChunk(map,groupNumber);
        for(Map<String,Integer> tokenMap:dataMap){
            CommandTokenTask commandTokenTask = new CommandTokenTask(tokenMap,groupNumber,restTemplateUtil,oauthAttributesUtil,tokenAttributesUtil);
            subTasks.add(commandTokenTask);
        }
        return subTasks;
    }

    /**
     * 推送
     */
    public Integer pull(Map<String,Integer> tokenMap){
        Integer result=0;
        if(cn.hutool.core.collection.CollectionUtil.isEmpty(tokenMap)){
            log.info("没有可推送的Token信息");
            return 0;
        }
        try{
            BaseResult baseResult = restTemplateUtil.post(restTemplateUtil.restOauthURL() + "/batchTokenValid",BaseResult.class,tokenMap);
            if(null == baseResult || !baseResult.getSuccess()){
                log.error("更新失败，Token：{}",tokenMap);
            }
            //更新本地Token
            Map<String,Integer> mapToken = (Map) baseResult.getData();
            if(!cn.hutool.core.collection.CollectionUtil.isEmpty(mapToken)){
                Iterator<Map.Entry<String, Integer>> entryIterator = mapToken.entrySet().iterator();
                while (entryIterator.hasNext()) {
                    Map.Entry<String, Integer> e = entryIterator.next();
                    if(1 != e.getValue()){
                        oauthAttributesUtil.remove(e.getKey());
                        tokenAttributesUtil.remove(e.getKey());
                        result++;
                    }
                }
            }
            log.info("验证Token是否过期成功，Token：{}-{}",tokenMap,result);
        }catch (Exception e){
            log.info("验证Token是否过期失败，Token：{}，ERROR:{}",tokenMap,e);
        }
        return result;
    }
}
